﻿using System;
using DragonsEyeAdventure.Utilities;

/*
 * Author: Nathaniel Edgar
 * Contributors:
 * File Version: v0.5
 * 
 * Copyright (C) 2013 Nathaniel Edgar
 * For full copyright information, please see the project README
 */

namespace DragonsEyeAdventure.Utilities
{
    /// <summary>
    /// Utility class for anything relating to console input/output
    /// </summary>
    abstract class Printer
    {
        #region Variables
        public const ConsoleColor defaultTextColor = ConsoleColor.Blue;
        #endregion

        #region Read/Write Methods
        /// <summary>
        /// Prints strings in a vertical line from a string array
        /// </summary>
        /// <param name="value">Array of strings to print</param>
        public static void printVertFromArray(string[] values)
        {
            for (int index = 0; index != values.Length; index++)
            {
                Console.Write(values[index]);
                cursorLeft(values[index].Length);
                cursorDown();
            }
        }

        /// <summary>
        /// Prints a string of characters in a vertical line
        /// </summary>
        /// <param name="value">String to print</param>
        public static void printVert(string value)
        {
            //Convert the string to string[] by setting each index to a char value
            char[] chars = value.ToCharArray();
            string[] output = new string[chars.Length];
            for (int charsLeft = 0; charsLeft != value.Length; charsLeft++)
            {
                output[charsLeft] = chars[charsLeft].ToString();
            }

            //Print the text with the new string[] value
            printVertFromArray(output);
        }

        /// <summary>
        /// Prints a box outline of a specified width and height at a specified X and Y location
        /// </summary>
        /// <param name="xOffset">Outline offset from left</param>
        /// <param name="yOffset">Outline offset from top</param>
        /// <param name="width">Width of outline</param>
        /// <param name="height">Height of outline</param>
        public static void printBox(int xOffset, int yOffset, int width, int height)
        {
            //Print the dashes on the top and bottom
            for (int dashes = 0; dashes != (width - 2); dashes++)
            {
                Console.SetCursorPosition((xOffset + 1) + dashes, yOffset);
                Console.Write("-");
                Console.SetCursorPosition((xOffset + 1) + dashes, yOffset + (height - 1));
                Console.Write("-");
            }

            //Print the left and right of the box
            //First the top chars,
            Console.SetCursorPosition(xOffset, yOffset);
            Console.Write("/");
            Console.SetCursorPosition(xOffset + (width - 1), yOffset);
            Console.Write("\\");
            //then the middle lines,
            for (int lines = 0; lines != (height - 2); lines++)
            {
                Console.SetCursorPosition(xOffset, (yOffset + 1) + lines);
                Console.Write("|");
                Console.SetCursorPosition(xOffset + (width - 1), (yOffset + 1) + lines);
                Console.Write("|");
            }
            //then the bottom chars
            Console.SetCursorPosition(xOffset, yOffset + (height - 1));
            Console.Write("\\");
            Printer.setCursorX(xOffset + (width - 1));
            Console.Write("/");
        }

        /// <summary>
        /// Prints a string in a "box" of a specified width and offsets it from 0,0 by specified values
        /// </summary>
        /// <param name="width">Width of "box"</param>
        /// <param name="xOffset">"Box" offset from left</param>
        /// <param name="yOffset">"Box" offset from top</param>
        /// <param name="value">Value to print</param>
        public static void printInBox(int width, int xOffset, int yOffset, string value)
        {
            //Set the initial cursor location
            setCursorY(yOffset);

            for (int nextChar = 0; nextChar != value.Length; nextChar++)
            {
                int getX = getCursorX();

                //If the line has wrapped,
                if (getX == 0)
                {
                    //set it to the left side of the box
                    setCursorX(xOffset);
                }

                //If the line has reached the right side,
                if (getX == xOffset + width)
                {
                    //set it also to the left side of the box
                    Console.WriteLine();
                    setCursorX(xOffset);
                }

                //Write the next character
                Console.Write(value[nextChar]);
            }
        }
        #endregion

        #region Position Methods
        /// <summary>
        /// Pushes the cursor back one space
        /// </summary>
        public static void cursorLeft()
        {
            Console.CursorLeft--;
        }

        /// <summary>
        /// Pushes the cursor back a specified number of spaces
        /// </summary>
        /// <param name="spaces">Number of spaces to go back</param>
        public static void cursorLeft(int spaces)
        {
            Console.CursorLeft -= spaces;
        }

        /// <summary>
        /// Pushes the cursor down one line
        /// </summary>
        public static void cursorDown()
        {
            Console.CursorTop++;
        }

        /// <summary>
        /// Pushes the cursor down a specified number of spaces
        /// </summary>
        /// <param name="lines">Number of lines to go down</param>
        public static void cursorDown(int lines)
        {
            Console.CursorTop += lines;
        }

        /// <summary>
        /// Sets Console.CursorLeft
        /// </summary>
        /// <param name="x">Distance from left</param>
        public static void setCursorX(int x)
        {
            Console.CursorLeft = x;
        }

        /// <summary>
        /// Sets Console.CursorTop
        /// </summary>
        /// <param name="x">Distance from top</param>
        public static void setCursorY(int y)
        {
            Console.CursorTop = y;
        }

        /// <summary>
        /// Returns current cursor x
        /// </summary>
        /// <returns>Distance from left</returns>
        public static int getCursorX()
        {
            return Console.CursorLeft;
        }

        /// <summary>
        /// Returns current cursor y
        /// </summary>
        /// <returns>Distance from top</returns>
        public static int getCursorY()
        {
            return Console.CursorTop;
        }
        #endregion

        #region Appearance Methods
        /// <summary>
        /// Sets Console.ForegroundColor
        /// </summary>
        /// <param name="color">Color to set foreground to</param>
        public static void setForeColor(ConsoleColor color)
        {
            Console.ForegroundColor = color;
        }
        #endregion
    }
}
